package client;

import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.Map;
import java.io.IOException;
import java.io.ObjectOutputStream;

import shared.WifiObject;
import android.content.SharedPreferences;
import android.net.wifi.WifiInfo;



/**
 * @author Donovan
 * 
 * Singleton class. This object can only be created by calling the getInstance() method
 * this prevents several clients being initialized on the device
 * 
 * IP address and port should be passed in before declaring getInstance()
 *
 */
public class Client {
	
	private Socket socket;
	private ObjectOutputStream output;
	private boolean isConnected;
	SharedPreferences settings = null;
	private static Client clientInstance;
	private static String ipAddress;

	private static int port;
	
		
	/**
	 * Constructor initializes a connection if possible
	 */
	private Client(){				
		try {
			socket = new Socket();
			SocketAddress address = new InetSocketAddress(ipAddress, port);
			socket.connect(address, 1000);
			if(socket.isConnected()){
				isConnected = true;
				output = new ObjectOutputStream(socket.getOutputStream());
			} else {
				isConnected = false;
			}		
		} catch (Exception e) {
			System.out.println(e);
		}
	}
	
	
	/**
	 * Can be called to try to connect to the server if the constructor fails
	 */
	public void tryConnect() {
		try {
			socket = new Socket();
			SocketAddress address = new InetSocketAddress(ipAddress, port);
			socket.connect(address, 1000);
			if(socket.isConnected()){
				isConnected = true;
				output = new ObjectOutputStream(socket.getOutputStream());
			} else {
				isConnected = false;
			}		
		} catch (Exception e) {
			System.out.println(e);
		}
	}
	
	
	/**
	 * Singleton entry point to the class. 
	 * Create an instance or get the instance by calling getInstance()
	 * 
	 * example:  Client c = Client.getInstance();
	 * 
	 * @return Client instance of the Client class
	 */
	public static Client getInstance() {
		if(clientInstance == null){
			if(ipAddress != "0.0.0.0" && port != 0){
				clientInstance = new Client();
	        } 
		} 
		return clientInstance;
	}
	
	public void killInstance(){
		clientInstance = null;
	}
		
	public static String getIpAddress() {
		return ipAddress;
	}

	public static void setIpAddress(String ipAddress) {
		Client.ipAddress = ipAddress;
	}

	public static int getPort() {
		return port;
	}

	public static void setPort(int port) {
		Client.port = port;
	}
	
	public boolean isConnected() {
		return isConnected;
	}

	/**
	 * Converts a wifiInfo object into a wifiObject
	 * and sends it to the server
	 * 
	 * @param wifiInfo
	 * @param otherNetworks 
	 * @param homeLocation 
	 * @param isProfile
	 */
	public void sendWifiObject(WifiInfo wifiInfo, boolean isProfile, Map<String, Integer> otherNetworks, String homeLocation){
		if(isConnected == true){
			try {
				if(wifiInfo != null){
					WifiObject wo = new WifiObject(wifiInfo.getSSID(), wifiInfo.getBSSID(), 
							wifiInfo.getMacAddress(), wifiInfo.getRssi(), wifiInfo.getLinkSpeed(), 
							wifiInfo.getNetworkId(), isProfile, otherNetworks, homeLocation);
					output.writeObject(wo);
				}
			} catch (IOException e) {
				System.out.println(e);
			}
		}
	}
}
